﻿namespace ExtendedWebBrowser2
{
    using mshtml;
    using System;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
    using System.Text.RegularExpressions;
    using System.Windows.Forms;

    public static class MSHtmlTool
    {
        private static Regex _regexPickNumber = new Regex(@"(?<number>[\d\.]+)", RegexOptions.IgnoreCase);
        private static Regex _regexTrimHtml = new Regex("</?(?!br)[^>]*>", RegexOptions.IgnoreCase);

        public static HtmlElement GetChildElementByClassName(this HtmlElement ele, string className, Action<string> logger)
        {
            foreach (HtmlElement child in ele.Children)
            {
                if (child.DomElement is DispHTMLDivElement)
                {
                    DispHTMLDivElement div = child.DomElement as DispHTMLDivElement;
                    if ((div != null) && (div.className == className))
                    {
                        return child;
                    }
                }
            }
            return null;
        }

        public static T GetChildHtmlDomByClassName<T>(this HtmlElement ele, string className) where T: mshtml.IHTMLElement
        {
            foreach (HtmlElement child in ele.Children)
            {
                if (child.DomElement is T)
                {
                    T childDiv = (T) child.DomElement;
                    if (!(string.IsNullOrEmpty(childDiv.className) || !(childDiv.className.ToString() == className.ToString())))
                    {
                        return childDiv;
                    }
                }
            }
            return default(T);
        }

        public static HtmlElement GetChildHtmlElementByClassName<T>(this HtmlElement ele, string className) where T: mshtml.IHTMLElement
        {
            foreach (HtmlElement child in ele.Children)
            {
                if (child.DomElement is T)
                {
                    T childDiv = (T) child.DomElement;
                    if (childDiv.className == className)
                    {
                        return child;
                    }
                }
            }
            return null;
        }

        public static DispHTMLDivElement GetDivInnerHtmlDomByClassName(this HtmlElementCollection collection, string className)
        {
            foreach (HtmlElement ele in collection)
            {
                if (ele.DomElement is DispHTMLDivElement)
                {
                    DispHTMLDivElement div = (DispHTMLDivElement) ele.DomElement;
                    if (div.className == className)
                    {
                        return div;
                    }
                }
            }
            return null;
        }

        public static string GetElementInnerTextById(HtmlDocument doc, string id)
        {
            if (doc == null)
            {
                //throw new ArgumentNullException("HtmlDocument is null");
                return null;
            }
            HtmlElement ele = doc.GetElementById(id);
            if (ele != null)
            {
                return ele.InnerText;
            }
            return null;
        }

        public static string GetElementInputValueById(HtmlDocument doc, string id)
        {
            if (doc == null)
            {
                throw new ArgumentNullException("HtmlDocument is null");
            }
            HtmlElement ele = doc.GetElementById(id);
            if (ele == null)
            {
                throw new Exception("找不到元素" + id);
            }
            if (ele.DomElement == null)
            {
                throw new Exception("找不到元素" + id + "的DOM");
            }
            if (ele.DomElement is IHTMLInputElement)
            {
                return (ele.DomElement as IHTMLInputElement).value;
            }
            return null;
        }

        public static T GetInnerHtmlDomByClassName<T>(this mshtml.IHTMLElementCollection collection, string className) where T: mshtml.IHTMLElement
        {
            foreach (T dom in collection)
            {
                if (dom.className == className)
                {
                    return dom;
                }
            }
            return default(T);
        }

        public static string KillHtml(string html)
        {
            return _regexTrimHtml.Replace(html, "");
        }

        public static string PickNumber(string html)
        {
            if (html == null)
            {
                return "";
            }
            Match m = _regexPickNumber.Match(html);
            if (m.Success)
            {
                return m.Groups["number"].Value;
            }
            return "0";
        }

        [DllImport("kernel32.dll")]
        private static extern bool SetLocalTime(ref SYSTEMTIME time);
        public static void SetLocalTime(DateTime dt)
        {
            SYSTEMTIME st;
            st.year = (short) dt.Year;
            st.month = (short) dt.Month;
            st.dayOfWeek = (short) dt.DayOfWeek;
            st.day = (short) dt.Day;
            st.hour = (short) dt.Hour;
            st.minute = (short) dt.Minute;
            st.second = (short) dt.Second;
            st.milliseconds = (short) dt.Millisecond;
            SetLocalTime(ref st);
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct SYSTEMTIME
        {
            public short year;
            public short month;
            public short dayOfWeek;
            public short day;
            public short hour;
            public short minute;
            public short second;
            public short milliseconds;
        }
    }
}

